package com.color.admin.common.security.config;

import com.color.admin.common.security.handler.JwtAuthenticationEntryPoint;
import com.color.admin.common.security.handler.JwtAuthenticationTokenFilter;
import com.color.admin.common.security.handler.JwtAuthenticationAccessDeniedHandler;
import com.color.admin.common.security.service.UserDetailsServiceImpl;
import com.color.admin.files.service.entity.SysFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @author HaiQiu
 * @date 2022/2/21
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    private JwtAuthenticationTokenFilter tokenFilter;

    @Autowired
    private JwtAuthenticationEntryPoint authenticationEntryPoint;

    @Autowired
    private JwtAuthenticationAccessDeniedHandler accessDeniedHandler;

    /**
     * 文件资源路径
     */
    @Autowired
    private SysFile sysFile;


    /**
     * 解决 无法直接注入 AuthenticationManager
     *
     * @return
     * @throws Exception
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception{
        return super.authenticationManagerBean();
    }



    /**
     * 自定义用户认证service和密码认证
     * @param auth
     * @throws Exception
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService).passwordEncoder(new PasswordEncoder() {
            @Override
            public String encode(CharSequence charSequence) {
                return charSequence.toString();
            }

            @Override
            public boolean matches(CharSequence charSequence, String s) {
                return charSequence.equals(s);
            }
        });
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .cors()
                .and()
                // 禁用 CSRF
                .csrf().disable()
                //未登录处理
                .exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint)
                .and()
                // 基于token，所以不需要session
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
                //请求验证
                .authorizeRequests()
                .anyRequest()
                .authenticated()
                .and().exceptionHandling()
                .accessDeniedHandler(accessDeniedHandler)
                // 防止iframe 造成跨域
                .and()
                .headers()
                .frameOptions()
                .disable()
                .and()
                .addFilterBefore(tokenFilter, UsernamePasswordAuthenticationFilter.class);
        http.cors();
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/swagger-ui.html","/swagger-ui/index.html","/v3/api-docs","/swagger-ui/**")
                .antMatchers("/webjars/**")
                .antMatchers("/v3/**")
                .antMatchers("/swagger-resources/**")
                .antMatchers("/static/**")
                //登录+验证码
                .antMatchers("/auth/authorization/login",
                        "/auth/authorization/captcha/check",
                        "/auth/authorization/captcha/get",
                        "/captcha/get",
                        "/captcha/check",
                        "/captcha/login/check")
                //放行资源文件
                .antMatchers("/resource/**"
                        ,"/druid/**");
    }
}
